package com.moogene.saad.gameplay.defender;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;

import com.moogene.android.engine.animlite.Animlite;
import com.moogene.android.engine.mmi.Book;
import com.moogene.android.engine.mmi.FTimerTask;
import com.moogene.android.engine.mmi.Layer;
import com.moogene.android.engine.util.MooMath;
import com.moogene.saad.gameplay.attacter.Attacker;
import com.moogene.saad.gameplay.bullet.Bullet;
import com.moogene.saad.gameplay.stages.Occupyable;

public class Tower extends Layer implements Occupyable{
	final private static int ALERT_RADIUS_UNIT = 16;

	/* The actual unint is 2<<4=16, this is for the performance */
	final private static int FIRE_INTERVAL_UNIT = 4;

	private final TowerTemplate towerTmplate;

	private Attacker target;

	private DefAction action;

	private boolean isInFireGap;

	private boolean isFixed;

	private final int range;

	private int row;

	private int col;
	
	private boolean canOccupyThis;

	public Tower(TowerTemplate towerTmplate) {
		super(towerTmplate.getWidth(), towerTmplate.getHeight());
		this.action = towerTmplate.getAction().clone();
		this.towerTmplate = towerTmplate;
		this.isInFireGap = false;
		range = towerTmplate.getRange() * ALERT_RADIUS_UNIT;
		setFixed(false);
	}

	@Override
	protected boolean canFoucs() {
		return true;
	}

	@Override
	protected boolean canDragFree() {
		return !isFixed;
	}

	@Override
	protected Animlite getAttachedAnimlite() {
		return action.getAnimlite();
	}

	public Attacker getTarget() {
		return target;
	}

	public void setFixed(boolean fixed) {
		isFixed = fixed;
		action.fix(fixed);
	}
	
	public void setCanOccupyThis(boolean canOccupy){
		this.canOccupyThis = canOccupy;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.moogene.android.engine.mmi.Layer#update()
	 */
	@Override
	public void update() {
		if (isFixed && target != null) {
			if (!isInScope(target) || target.isDead()) {
				target = null;
			} else {
				action.allert(x, y, target);
				fire(target);
			}
		}
		ControlButtons cb = ControlButtons.getInstance();
		if (isEndFocus()) {
			if (!cb.isInAction()) {
				cb.disappear();
			}
		}

		if (isStartHold()) {
			cb.link(this);
			cb.disappear();
		}
		if (isEndHold()) {
			cb.show();
		}
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see com.moogene.android.engine.mmi.Layer#draw(android.graphics.Canvas)
	 */
	@Override
	public void draw(Canvas canvas) {
		super.draw(canvas);
		if (isFocused()) {
			Paint p = new Paint();
			if(canOccupyThis){
				p.setColor(0x3026FF4D);
			}else{
				p.setColor(0x30FF0000);
			}
			p.setStyle(Style.FILL_AND_STROKE);
			canvas.drawCircle(getX(), getY(), range, p);
		}
	}

	private void fire(Attacker attacker) {
		if (isInFireGap) {
			return;
		}
		Book.getInstance().schedule(
				new FTimerTask(
						towerTmplate.getFrequency() << FIRE_INTERVAL_UNIT) {
					@Override
					public void run() {
						isInFireGap = false;
					}
				});
		isInFireGap = true;
		action.fire();
		// Bullet bullet = new Bullet(attacker, towerTmplate.getEffectable(),
		// towerTmplate.getBulletAnim(), towerTmplate.getBulletSpeed());
		Bullet bullet = towerTmplate.createBullet();
		bullet.setLocation(x, y);
		bullet.shoot(attacker);
		// if (bullet.hasBody()) {
		// bullet.setLocation(x, y);
		// if (!bullet.isGuilded()){
		// bullet.getAnimlite().getRotateAnim().setDegree(attacker.getX(),
		// attacker.getY(), x, y);
		// }
		// }

		// if (towerTmplate.getBulletAnim() == null) {
		// bullet = new Bullet(attacker, towerTmplate.getEffectable());
		// } else {
		// bullet = new Bullet(attacker, towerTmplate.getEffectable(),
		// towerTmplate.getBulletAnim(), towerTmplate.getBulletSpeed());
		// }
		Book.getInstance().getCurrentPage().addLayer(bullet);
	}

	public void scanEnemy(Attacker attacker) {
		if (isInScope(attacker)) {
			target = attacker;
		}
	}

	private boolean isInScope(Attacker attacker) {
		if (MooMath.fastDistance(attacker.getX() - getX(), attacker.getY()
				- getY()) <= range) {
			return true;
		}
		return false;
	}

	@Override
	public void setAlign(int row, int col) {
		this.row = row;
		this.col = col;
		this.x = (col << 7) + 64;
		this.y = (row << 7) + 64;
	}

	public Bitmap getPreview() {
		return towerTmplate.getAction().getAnimlite().getFrameAnim()
				.getPreview(0);
	}

	public Animlite getAnimlite() {
		return towerTmplate.getAction().getAnimlite();
	}

	@Override
	public Rect getDstRect() {
		if (action != null) {
			return action.getAnimlite().getDstRect(x, y);
		}
		return null;
	}
}
